package com.example.game_dafangdaxie.algorithm;

import com.example.game_dafangdaxie.StringConstant.PIECE;
import com.example.game_dafangdaxie.StringConstant.Point;
import com.example.game_dafangdaxie.StringConstant.TouchList;
import com.example.game_dafangdaxie.StringConstant.TouchXY;

import java.util.ArrayList;
import java.util.Random;

/****
 * create by LiuTong
 * 2021.9.30
 */

public class ProAI {

    private static ConditionalJudgment cj, cj1;
    private ArrayList<TouchXY> xyArrayList;

    public ProAI(ArrayList<TouchXY> xyArrayList) {
        this.xyArrayList = xyArrayList;
    }

    /***
     * pre为1时，为预下棋判断
     */
    private Point getOneStepsShapingPoint(int Piece) {
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                Point newPint = new Point(i, j);
                if (!TouchList.Contains(xyArrayList, newPint)) {
                    cj = new ConditionalJudgment(newPint, xyArrayList, Piece, 1);
                    if (cj.isGameLong()) {
                        return newPint;
                    }
                    if (cj.isGameFive()) {
                        return newPint;
                    }
                    if (cj.isGameFour()) {
                        return newPint;
                    }
                    if (cj.isFang()) {
                        return newPint;
                    }
                    if (cj.isThree()) {
                        return newPint;
                    }
                }//if !=
            }
        }
        return null;
    }

    /***
     * 获取有利的点
     */
    private int getScore(Point bestPoint) {
        int scoreBlue = 0;
        int scoreRed = 0;
        if (!TouchList.Contains(xyArrayList, bestPoint)) {
            scoreBlue = 0;
            scoreRed = 0;
            cj = new ConditionalJudgment(bestPoint, xyArrayList, PIECE.BLUE, 1);
            cj1 = new ConditionalJudgment(bestPoint, xyArrayList, PIECE.RED, 1);
            if (cj.isGameLong()) {
                scoreBlue = 100;
            } else if (cj.isGameFive()) {
                scoreBlue = 80;
            } else if (cj.isGameFour() || cj.isThree() || cj.isFang()) {

                scoreBlue = 60;

            }

            if (cj1.isGameLong()) {
                scoreBlue = 20;
            } else if (cj1.isGameFive()) {
                scoreBlue = 15;
            } else if (cj1.isGameFour() || cj1.isThree() || cj1.isFang()) {
                scoreBlue = 10;
            }
        }

        return scoreBlue + scoreRed;
    }

    private int getLowScore(Point bestPoint) {
        int scoreBlue = 0;
        int scoreRed = 0;
        if (!TouchList.Contains(xyArrayList, bestPoint)) {
            scoreBlue = 0;
            scoreRed = 0;
            cj = new ConditionalJudgment(bestPoint, xyArrayList, PIECE.BLUE, 2);
            cj1 = new ConditionalJudgment(bestPoint, xyArrayList, PIECE.RED, 2);
            if (cj.isGameLong()) {
                scoreBlue = 4;
            } else if (cj.isGameFive()) {
                scoreBlue = 3;
            } else if (cj.isGameFour() || cj.isThree() || cj.isFang()) {
                if (scoreBlue == 0) {
                    scoreBlue = 2;
                }
            }

            if (cj1.isGameLong()) {
                scoreBlue = 3;
            } else if (cj1.isGameFive()) {
                scoreBlue = 2;
            } else if (cj1.isGameFour() || cj1.isThree() || cj1.isFang()) {
                scoreBlue = 1;
            }
        }

        return scoreBlue + scoreRed;
    }

    public Point getBestPoint() {
        int maxScore = 0;
        Point bestPoint = new Point(-1, -1);
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                Point point = new Point(i, j);
                if (getScore(point) > maxScore) {
                    maxScore = getScore(point);
                    bestPoint = new Point(point.x, point.y);
                }
            }
        }
        return bestPoint;
    }

    public Point getLowBestPoint() {
        int maxScore = 0;
        Point lowBestPoint = new Point(-1, -1);
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                Point point = new Point(i, j);
                if (getLowScore(point) > maxScore) {
                    maxScore = getLowScore(point);
                    lowBestPoint = new Point(point.x, point.y);
                }
            }
        }
        return lowBestPoint;
    }

    /***
     * pre 为2时，预下两步
     */
    private Point getTwoStepsShapingPoint(int Piece) {
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                if (!TouchList.Contains(xyArrayList, new Point(i, j))) {
                    Point newPoint = new Point(i, j);
                    cj = new ConditionalJudgment(newPoint, xyArrayList, PIECE.BLUE, 2);
                    if (cj.isThree()) {
                        return newPoint;
                    }
                    if (cj.isFang()) {
                        return newPoint;
                    }
                    if (cj.isGameFive()) {
                        return newPoint;
                    }
                    if (cj.isGameFive()) {
                        return newPoint;
                    }
                    if (cj.isGameLong()) {
                        return newPoint;
                    }
                }//if arrayChess
            }
        }
        return null;
    }

    private Point getProAiSelectPoint() {
        if (getOneStepsShapingPoint(PIECE.BLUE) != null) {
            getOneStepsShapingPoint(PIECE.BLUE);
        }
        if (getOneStepsShapingPoint(PIECE.RED) != null) {
            return getOneStepsShapingPoint(PIECE.RED);
        }

        if (getTwoStepsShapingPoint(PIECE.BLUE) != null) {
            getTwoStepsShapingPoint(PIECE.BLUE);
        }
        if (getTwoStepsShapingPoint(PIECE.RED) != null) {
            getTwoStepsShapingPoint(PIECE.RED);
        }
        return null;
    }

    /****
     * 处理 getProAiSelectPoint==null的情况，随机落子
     */
    public Point getAllPoint() {
        ArrayList<Point> nullPoint = new ArrayList<>();
        int size ;
        Random random = new Random();
        if (getBestPoint().x != -1 && getBestPoint().y != -1) {
            return getBestPoint();
        } else if (getLowBestPoint().x != -1 && getLowBestPoint().y != -1) {
            return getLowBestPoint();
        } else if (getProAiSelectPoint() != null) {
            return getProAiSelectPoint();
        } else {
            for (int i = 0; i < 6; i++) {
                for (int j = 0; j < 6; j++) {
                    if (!TouchList.Contains(xyArrayList, new Point(i, j))) {
                        nullPoint.add(new Point(i, j));
                    }
                }
            }
            size = nullPoint.size();
        }
        int Num = random.nextInt(36) + 1;
        if (size != 0) {
            return nullPoint.get(Num % size);
        }
        return null;
    }

}
